package com.yx.cloud.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.aaa.lib.map.MapUtils;
import com.alibaba.ailabs.tg.utils.LogUtils;
import com.iot.product.sweeper.bean.BaseStation;

public class HSVColorPickerView extends View {
    Paint paint;
    LinearGradient linearGradient;
    SweepGradient sweepGradient;
    int strokWidth = 30;
    float[] hsv = new float[3];
    float brightness;
    private int TOUCH_TYPE_NONE = 0;
    private int TOUCH_TYPE_HUE = 1;
    private int TOUCH_TYPE_SV = 2;
    private int mode;
    private int svRadius;
    private int hRadius;
    private int hCursorRadius;
    private int svCursorRadius;
    private int width;
    private int height;
    private int touchType;

    private int circleCenterX;
    private int circleCenterY;
    private int[] innerCircleColor;
    private Bitmap innerCircleBitmap;
    private LightChangeListener listener;
    private TouchEventListener eventListener;


    public HSVColorPickerView(Context context) {
        super(context);
        init();
    }

    public HSVColorPickerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     *  求向量夹角
     *  向量积 v1*v2= x1*x2+y1*y2=|v1|*|v2|*cosθ
     *  cosθ= (x1*x2+y1*y2) /(√(x1*x1+y1*y1) * √(x2*x2+y2*y2))
     * @param x1 初始向量x
     * @param y1 初始向量y
     * @param x2 结束向量x
     * @param y2 结束向量y
     * @return 向量夹角0-360 有顺序
     */
    private static double getAngle(float x1, float y1, float x2, float y2) {
        double angle = Math.acos((x1 * x2 + y1 * y2) / Math.sqrt(x1 * x1 + y1 * y1) / Math.sqrt(x2 * x2 + y2 * y2));
        double mol = x1 * y2 - x2 * y1;
        if (mol > 0) {
            return angle;
        } else {
            return 2 * Math.PI - angle;
        }
    }

    public int getMode() {
        return mode;
    }

    public void setMode(int mode) {
        this.mode = mode;
        sweepGradient = null;
        linearGradient = null;
        postInvalidate();
    }

    public void setOnLightSelectedListener(LightChangeListener listener) {
        this.listener = listener;
    }

    public void setEventListener(TouchEventListener eventListener) {
        this.eventListener = eventListener;
    }

    private void init() {
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        hsv[0] = 0;
    }

    public void setBrightness(float brightness) {
        this.brightness = brightness;
    }

    public int getColor() {
        return Color.HSVToColor(hsv);
    }

    public void setColor(int color) {
        Color.colorToHSV(color, hsv);
        postInvalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        double distanceToCenter = Math.sqrt((x - circleCenterX) * (x - circleCenterX) + (y - circleCenterY) * (y - circleCenterY));

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (eventListener != null) {
                eventListener.onEventHandle(true);
            }

            if (Math.abs(distanceToCenter - hRadius) < strokWidth) {
                touchType = TOUCH_TYPE_HUE;
            } else if (distanceToCenter <= svRadius) {
                touchType = TOUCH_TYPE_SV;
            } else {
                touchType = TOUCH_TYPE_NONE;
            }
            changeLight(x, y, false);
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            changeLight(x, y, false);
        } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
            changeLight(x, y, true);
            if (eventListener != null) {
                eventListener.onEventHandle(false);
            }
        }

        postInvalidate();
        return true;
    }

    private void changeLight(float x, float y, boolean isChanged) {
        if (touchType == TOUCH_TYPE_HUE) {
            double angle = getAngle(circleCenterX, 0, (x - circleCenterX), (y - circleCenterY)) / Math.PI * 180;
            LogUtils.i("angle : " + angle);
            if (angle >= 0 && angle <= 90) {
                angle = 359;
            }
            if (angle <= 180 && angle > 90) {
                angle = 181;
            }

            if (mode == BaseStation.LIGHT_TYPE_COLORFUL) {
                //白光修改条条是修改hue
                hsv[0] = (float) (angle - 180) * 2;
                linearGradient = null;
                if (listener != null) {
                    listener.onLightChange(hsv, isChanged);
                }
            } else if (mode == BaseStation.LIGHT_TYPE_WHITE) {

                //白光修改条条是修改亮度
                brightness = 1 - (float) (angle - 180) * 2 / 360;
                if (listener != null) {
                    listener.onLightChange(new float[]{0, 1, brightness}, isChanged);
                }
            }
        } else if (touchType == TOUCH_TYPE_SV) {
            //只有彩光能改sv
            if (mode == BaseStation.LIGHT_TYPE_COLORFUL) {
                float verctorToCenterX = x - circleCenterX;
                float verctorToCenterY = y - circleCenterY;
                if (x > circleCenterX) {
                    if (Math.abs(verctorToCenterY) + verctorToCenterX > svRadius) {
                        //超出三角形部分直接设置为1
                        hsv[1] = 1;
                    } else {
                        hsv[1] = (float) (1 - MapUtils.pointToLine(x, y, circleCenterX, circleCenterY - svRadius, circleCenterX + svRadius, circleCenterY) / (Math.sqrt(2) * svRadius));
                    }
                    hsv[2] = (float) (1 - MapUtils.pointToLine(x, y, circleCenterX, circleCenterY - svRadius, circleCenterX - svRadius, circleCenterY) / (Math.sqrt(2) * svRadius));
                } else {
                    if (Math.abs(verctorToCenterY) + Math.abs(verctorToCenterX) > svRadius) {
                        //超出三角形部分直接设置为1
                        hsv[2] = 1;
                    } else {
                        hsv[2] = (float) (1 - MapUtils.pointToLine(x, y, circleCenterX, circleCenterY - svRadius, circleCenterX - svRadius, circleCenterY) / (Math.sqrt(2) * svRadius));
                    }
                    hsv[1] = (float) (1 - MapUtils.pointToLine(x, y, circleCenterX, circleCenterY - svRadius, circleCenterX + svRadius, circleCenterY) / (Math.sqrt(2) * svRadius));
                }

                if (listener != null) {
                    listener.onLightChange(hsv, isChanged);
                }
            }
        }
    }

    private void createInnerCircleBitmap(float hue) {
        if (innerCircleColor == null) {
            innerCircleColor = new int[(int) svRadius * (int) svRadius * 2];
        }

        float[] imgHSV = new float[3];
        for (int i = 0; i < innerCircleColor.length; i++) {
            int x = i % ((int) svRadius * 2);
            int y = i / ((int) svRadius * 2);
            double distanceToCenter = Math.sqrt((x - svRadius) * (x - svRadius) + (y - svRadius) * (y - svRadius));
            if (distanceToCenter <= svRadius) {
                imgHSV[0] = hue;
                imgHSV[1] = (float) distanceToCenter / svRadius;
                int alpha = (int) (Math.min((float) x / svRadius / 2, 1) * 255);
                imgHSV[2] = 1;

                innerCircleColor[i] = Color.HSVToColor(alpha, imgHSV);
            } else {
                innerCircleColor[i] = Color.WHITE;
            }
        }

        if (innerCircleBitmap != null && !innerCircleBitmap.isRecycled()) {
            innerCircleBitmap.recycle();
        }
        innerCircleBitmap = Bitmap.createBitmap(innerCircleColor, svRadius * 2, svRadius, Bitmap.Config.ARGB_8888);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        width = getWidth();
        height = getHeight();
        float innerCircleLeft = width / 9f;
        float innerCircleRight = width * 8 / 9f;
        circleCenterX = width / 2;
        circleCenterY = height;
        svRadius = (int) (innerCircleRight - innerCircleLeft) / 2;
        strokWidth = (int) innerCircleLeft * 1 / 2;
        hCursorRadius = strokWidth * 2 / 3;
        svCursorRadius = strokWidth / 2;
        hRadius = svRadius + strokWidth * 3 / 2;


        if (mode == BaseStation.LIGHT_TYPE_WHITE) {
            drawWhiteLight(canvas);
        } else if (mode == BaseStation.LIGHT_TYPE_COLORFUL) {
            drawColorfulLight(canvas);
        } else if (mode == BaseStation.LIGHT_TYPE_RAINBOW) {
            drawRainbowLight(canvas);
        }

    }

    private void drawRainbowLight(Canvas canvas) {
        if (sweepGradient == null) {
            sweepGradient = new SweepGradient(circleCenterX, circleCenterY,
                    new int[]{0xffffffff, 0xffffffff, 0xffFF7F7F, 0xffF59DF5, 0xff99B8FF, 0xff7FFFFF, 0xff8EFB8E, 0xffF5EA7D, 0xffFF7F7F},
                    new float[]{0, 0.5f, 0.5f, 0.5f + 0.5f / 6, 0.5f + 0.5f / 6 * 2, 0.5f + 0.5f / 6 * 3, 0.5f + 0.5f / 6 * 4, 0.5f + 0.5f / 6 * 5, 0.5f + 0.5f / 6 * 6});
        }

        paint.setShader(null);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(0xffD9DADC);
        canvas.drawArc(circleCenterX - svRadius, circleCenterY - svRadius, circleCenterX + svRadius, circleCenterY + svRadius, 180, 360, true, paint);

        paint.setShader(null);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokWidth + 2);
        paint.setColor(0xffD9DADC);
        canvas.drawArc(circleCenterX - hRadius - 2, circleCenterY - hRadius - 2, circleCenterX + hRadius + 2, circleCenterY + hRadius + 2, 180, 360, true, paint);

        paint.setShader(sweepGradient);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokWidth);
        canvas.drawArc(circleCenterX - hRadius, circleCenterY - hRadius, circleCenterX + hRadius, circleCenterY + hRadius, 180, 360, true, paint);

    }

    private void drawWhiteLight(Canvas canvas) {
        if (sweepGradient == null) {
            sweepGradient = new SweepGradient(circleCenterX, circleCenterY,
                    new int[]{0xffffffff, Color.HSVToColor(new float[]{37, 0.08f, 1}), Color.HSVToColor(new float[]{37, 0.58f, 1})},
                    new float[]{0, 0.5f, 1f});
        }

        paint.setShader(null);
        paint.setStyle(Paint.Style.FILL);
        int whiteColor = Color.HSVToColor(new float[]{37, (1-brightness) * 0.5f + 0.08f, 1});
        paint.setColor(whiteColor);
        canvas.drawArc(circleCenterX - svRadius, circleCenterY - svRadius, circleCenterX + svRadius, circleCenterY + svRadius, 180, 360, true, paint);

        paint.setShader(null);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokWidth + 2);
        paint.setColor(0xffD9DADC);
        canvas.drawArc(circleCenterX - hRadius + 2, circleCenterY - hRadius - 1, circleCenterX + hRadius + 2, circleCenterY + hRadius + 2, 180, 360, true, paint);

        paint.setShader(sweepGradient);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokWidth);
        canvas.drawArc(circleCenterX - hRadius, circleCenterY - hRadius, circleCenterX + hRadius, circleCenterY + hRadius, 180, 360, true, paint);

        //绘制hue游标
        int angle = 360 - (int) (brightness * 360) / 2;
        canvas.save();
        paint.setShader(null);
        paint.setStyle(Paint.Style.FILL);
        canvas.translate(circleCenterX, circleCenterY);
        canvas.rotate(angle);
        paint.setColor(Color.LTGRAY);
        canvas.drawCircle(hRadius, 0, hCursorRadius + 1, paint);
        paint.setColor(Color.WHITE);
        canvas.drawCircle(hRadius, 0, hCursorRadius, paint);

        canvas.restore();

    }

    private void drawColorfulLight(Canvas canvas) {

        if (linearGradient == null || sweepGradient == null) {

            linearGradient = new LinearGradient(circleCenterX - svRadius, circleCenterY, circleCenterX + svRadius, circleCenterY, new int[]{Color.HSVToColor(new float[]{hsv[0], 0.1f, 1f}), Color.HSVToColor(new float[]{hsv[0], 1f, 1f}), Color.HSVToColor(new float[]{hsv[0], 1f, 0.6f})}, null, Shader.TileMode.CLAMP);
            sweepGradient = new SweepGradient(circleCenterX, circleCenterY,
                    new int[]{0xffffffff, 0xffffffff, 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff, 0xff0000ff, 0xffff00ff, 0xffff0000},
                    new float[]{0, 0.5f, 0.5f, 0.5f + 0.5f / 6, 0.5f + 0.5f / 6 * 2, 0.5f + 0.5f / 6 * 3, 0.5f + 0.5f / 6 * 4, 0.5f + 0.5f / 6 * 5, 0.5f + 0.5f / 6 * 6});
        }
        //画半圆
        paint.setShader(linearGradient);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawArc(circleCenterX - svRadius, circleCenterY - svRadius, circleCenterX + svRadius, circleCenterY + svRadius, 180, 360, true, paint);

        paint.setShader(null);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokWidth + 2);
        paint.setColor(0xffD9DADC);
        canvas.drawArc(circleCenterX - hRadius + 2, circleCenterY - hRadius - 1, circleCenterX + hRadius + 2, circleCenterY + hRadius + 2, 180, 360, true, paint);

        paint.setShader(sweepGradient);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokWidth);
        canvas.drawArc(circleCenterX - hRadius, circleCenterY - hRadius, circleCenterX + hRadius, circleCenterY + hRadius, 180, 360, true, paint);

        //绘制hue游标
        int angle = (int) hsv[0] / 2 + 180;
        canvas.save();
        paint.setShader(null);
        paint.setStyle(Paint.Style.FILL);
        canvas.translate(circleCenterX, circleCenterY);
        canvas.rotate(angle);
        paint.setColor(Color.LTGRAY);
        canvas.drawCircle(hRadius, 0, hCursorRadius + 1, paint);
        paint.setColor(Color.WHITE);
        canvas.drawCircle(hRadius, 0, hCursorRadius, paint);

        canvas.restore();

        //绘制sv游标
        float cursorX = (1 - hsv[2]) * svRadius - (1 - hsv[1]) * svRadius;
        float cursorY = (1 - hsv[2]) * svRadius + (1 - hsv[1]) * svRadius;
        paint.setShader(null);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.LTGRAY);
        paint.setStrokeWidth(svCursorRadius / 3 + 2);
        canvas.drawCircle(circleCenterX + cursorX, circleCenterY - svRadius + cursorY, svCursorRadius, paint);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(svCursorRadius / 3);
        paint.setColor(Color.WHITE);
        canvas.drawCircle(circleCenterX + cursorX, circleCenterY - svRadius + cursorY, svCursorRadius, paint);
    }

    public interface LightChangeListener {
        void onLightChange(float[] hsv, boolean changed);
    }

    public interface TouchEventListener {
        void onEventHandle(boolean isUsing);
    }
}
